/**
 * 
 */
package multidomain;

import java.util.HashMap;
import java.util.Vector;

import multidomain.TED.TableRow;
import tracing.Tracer;
import util.Auxiliar;
import util.Dijkstra;
import util.WeightedGraph;
import wdmsim.OXC;
import wdmsim.PhysicalTopology;
import wdmsim.WDMLink;
import controlPlane.PCE;

/**
 * @author alissonslp
 *
 */
public class TED2 {

	PhysicalTopology pt = PhysicalTopology.getInstance();
	Tracer trace = Tracer.getTracerObject();
	Domain[] domainVector = pt.getDomainVector();
	boolean[][] adjDomainMatrix = pt.getAdjacencyDomainMatrix();
	WeightedGraph domainsGraph = pt.getDomainWeightedGraph();
	int id;
	//HashMap<OXC,Vector<TableRow>> intradomainTable;
	HashMap<Domain,Vector<TableRow>> multidomainTable;	
	
	// 					Representation of domain's 0 TED
	// ---------------------------------------------------------------------------------------
	//	destination	|	inBorderNode	|		path		|	cost	| 	wavelengths
	// ---------------------------------------------------------------------------------------
	//		1		|		1			|	(0,1)			|	4		|	(0,1,4,12)
	//		1		|		2			|	(0,11,10,2,1)	|	3		| 	(1,5,8)
	//		2		|		5			|	(0,1,2)			|	5		|	(0,1,8,14,20)	
	//		2		|		4			|	(0,11,10,2)		|	6		| 	(2,3,5,18,21,23)
	// ---------------------------------------------------------------------------------------
	
	/**
	 * Class that represents a row of the TED
	 * @author Alisson
	 *
	 */
	public static class TableRow implements Cloneable {
		public int id;
		public int[] path;
		public int[] costs;
		public int[] wavelengths;
		public int inBorderNode;
		public int[] freeWavelengths;
		
		protected Object clone() throws CloneNotSupportedException {
		    TableRow clone = (TableRow)super.clone();
		    return clone;
		}
		
		public TableRow(int id, int borderNode, int[] freeWavelengths, int[] cost, int[] path, int[] wavelengthsBandwidth) {
			this.id = id;
			this.freeWavelengths = freeWavelengths;
			this.path = path;
			this.inBorderNode = borderNode;
			this.wavelengths = wavelengthsBandwidth;
			this.costs = cost;
		}
		
		public TableRow(int id, int borderNode, int[] freeWavelengths, int[] path, int[] wavelengthsBandwidth) {
			this.id = id;
			this.freeWavelengths = freeWavelengths;
			this.path = path;
			this.inBorderNode = borderNode;
			this.wavelengths = wavelengthsBandwidth;
		}
		
		public TableRow(TableRow tableRow) {
			this.id = tableRow.id;
			this.costs = tableRow.costs;
			this.path = tableRow.path;
			this.wavelengths = tableRow.wavelengths;
		}
		
		public TableRow(int id, int[] costs, int[] domainPath, int[] wavelengths) {
			this.id = id;
			this.costs = costs;
			this.path = domainPath;
			this.wavelengths = wavelengths;
		}
		
		/**
		 * @param dst
		 * @param id2
		 * @param availableWavelengths
		 * @param domainPath
		 */
		public TableRow(int id, int inBorderNode, int[] availableWavelengths, int[] domainPath) {
			this.id = id;
			this.inBorderNode = inBorderNode;
			this.wavelengths = availableWavelengths;
			this.path = domainPath;
		}

		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public int[] getCosts() {
			return costs;
		}

		public void setCosts(int[] costs) {
			this.costs = costs;
		}

		public int getCost(int index) {
			return costs[index];
		}
		
		public void setCost(int wavelength, int cost) {
			this.costs[wavelength] = cost;
		}
		
		public int[] getPath() {
			return path;
		}

		public void setPath(int[] path) {
			this.path = path;
		}
		
		public int getPath(int i) {
			return path[i];
		}
		
		public int getInBorderNode() {
			return this.inBorderNode;
		}
		
		public void setInBorderNode(int bn) {
			this.inBorderNode = bn;
		}		
		
		public int[] getWavelengthsBandwidth() {
			return wavelengths;
		}
		
		public int getWavelengthAvailableBandwidth(int wavelength) {
			return wavelengths[wavelength];
		}

		public void setAvailableWavelengths(int[] wavelengths) {
			this.wavelengths = wavelengths;
		}
		
		public void setAvailableWavelength(int wavelength, int cost) {
			this.wavelengths[wavelength] = cost;
		}
		
		public int[] getFreeWavelengths() {
			return freeWavelengths;
		}
		
		public void setFreeWavelengths(int[] freeWavelengths) {
			this.freeWavelengths = freeWavelengths;
		}

		public boolean hasWavelength(int wavelength) {
			// TODO Auto-generated method stub
			return false;
		}
		
		/**
		 * atribui a wavelength o valor do wavelenght do caminho e retorna o caminho
		 * 
		 * @param tableRowVector
		 * @param wavelength
		 * @return
		 */
		public static TableRow getBestPath(Vector<TableRow> tableRowVector, Integer wavelength) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getBestPath(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getSmallestPath(Vector<TableRow> tableRowVector, int wavelength) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getSmallestPath3(Vector<TableRow> tableRowVector, int wavelength) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com menor caminho (em saltos) e maior bandwidth disponivel (nesta ordem)
		public static TableRow getSmallestPath(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com menos bandwidth disponivel (nesta ordem)
		public static TableRow getSmallestPath3(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com inBorderNode==borderNode, com menor caminho (em saltos) e maior bandwidth disponivel (nesta ordem)
		public static TableRow getSmallestPath(int borderNode, Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com inBorderNode==borderNode, com menor caminho (em saltos) e maior bandwidth disponivel (nesta ordem)
		public static TableRow getSmallestPathF(int borderNode, Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com mais bandwidth disponivel fim a fim
		public static TableRow getSmallestPath2(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		// retorna o tableRow com mais bandwidth disponivel fim a fim
		public static TableRow getShortesttPath(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getShortestPathF(Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getShortestPathF(Vector<TableRow> tableRowVector, int wavelength) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);
		}
		
		public static TableRow getShortestPathF(int borderNode, Vector<TableRow> tableRowVector) {
			// TODO Auto-generated method stub
			return new TableRow(0, new int[0], new int[0], new int[0]);			
		}
	} // end of tableRow
	
	
	///////////////////////////////////////////////////////////
	// methods of TED
	//
		
	public TED2(int id) throws Exception {
		// TODO Auto-generated method stub
	}

	public HashMap<Domain,Vector<TableRow>> getMultidomainTable() {
		return this.multidomainTable;
	}
	
	public boolean hasRegister(Domain domain) {
		// TODO Auto-generated method stub
		return false;
	}
	
	// atualiza a ted de pce de acordo com a ted de this
	public void update(PCE pce) throws Exception {
		// TODO Auto-generated method stub
	}
	
	// 
	/**
	 * atualiza a ted de pce de acordo com a ted de this, agora considerando as porcoes intradomain
	 * 
	 * @param pce
	 */
	public void update2(PCE pce) throws Exception {
		// TODO Auto-generated method stub
	}
	
	public void updateF(PCE pce) throws Exception {
		// TODO Auto-generated method stub
	}
	
	public void update() throws Exception {
		// TODO Auto-generated method stub
	}
	
	/**
	 * 
	 * @throws Exception
	 */
	public void update2() throws Exception {
		// TODO Auto-generated method stub
	}
	
	public void updateF() throws Exception {
		// TODO Auto-generated method stub
	}
	
	public int[] getBestMultidomainPathF(int borderNode, int domainId, int resources, Integer wavelength) {
		// TODO Auto-generated method stub
		return new int[0];
	}
	
	public int[] getBestMultidomainPathF(int domainId, int resources) {
		// TODO Auto-generated method stub
		return new int[0];
	}
	
	public TableRow getBestMultidomainRowF(int domainId, int resources) {
		// TODO Auto-generated method stub
		return new TableRow(0, new int[0], new int[0], new int[0]);
	}
	
	public TableRow getBestMultidomainRowF(int borderNode, int domainId, int resources, Integer wavelength) {
		// TODO Auto-generated method stub
		return new TableRow(0, new int[0], new int[0], new int[0]);
	}
	
	private void generateMultidomainDatabaseF() throws Exception {
		// TODO Auto-generated method stub
	}
	
	/**
	 * 
	 * @param dst: id do dominio destino
	 * @param row
	 */
	public void addPath(int dst, TableRow row) {
		// TODO Auto-generated method stub
	}
	
	/**
	 * @throws Exception 
	 * 
	 */
	private void generateMultidomainDatabase() throws Exception {
		// TODO Auto-generated method stub
	}

	/**
	 * @throws Exception 
	 * 
	 */
	private void generateMultidomainDatabase2() throws Exception {
		// TODO Auto-generated method stub
	}
	
	public TableRow getBestMultidomainRow(int domainId) {
		// TODO Auto-generated method stub
		return new TableRow(0, new int[0], new int[0], new int[0]);
	}
	
	public TableRow getBestMultidomainRow(int borderNode, int domainId) {
		// TODO Auto-generated method stub
		return new TableRow(0, new int[0], new int[0], new int[0]);
	}
	
	public TableRow getShortestMultidomainRow(int borderNode, int domainId) {
		// TODO Auto-generated method stub
		return new TableRow(0, new int[0], new int[0], new int[0]);
	}
	
	/**
	 * Verifica na tabela de roteamento se ha caminho entre seu dominio e o dominio 
	 * domainId com quantidade de recursos maior ou igual a resources 
	 * 
	 * @param domainId
	 * @param resources
	 * @return
	 */
	public int[] getBestMultidomainPath(int domainId, int resources) {
		// TODO Auto-generated method stub
		return new int[0];
	}
	
	public int[] getBestMultidomainPath2(int domainId, int resources) {
		// TODO Auto-generated method stub
		return new int[0];
	}
	
	// retorna um tableRow com wavelength com recources suficientes
	public int[] getBestMultidomainPath(int domainId, int resources, Integer wavelength) {
		// TODO Auto-generated method stub
		return new int[0];
		
	}
	
	// retorna um tableRow com wavelength com recources suficientes e inBorderNode = borderNode
	public int[] getBestMultidomainPath(int borderNode, int domainId, int resources, Integer wavelength) {
		// TODO Auto-generated method stub
		return new int[0];
		
	}
	
	public Vector<Integer> getMultidomainCandidateWavelengths(int domainId, int resources) {
		// TODO Auto-generated method stub
		return new Vector<Integer>();
	}
	
	public Vector<Integer> getMultidomainCandidateWavelengths(int domainId, int src, int resources) throws Exception {
		// TODO Auto-generated method stub
		return new Vector<Integer>();
	}
	public Vector<Integer> getMultidomainCandidateWavelengths2(int domainId, int src, int resources) throws Exception {
		// TODO Auto-generated method stub
		return new Vector<Integer>();
	}
	
	public int getBestMultidomainWavelength(int domainId, int resources) {
		// TODO Auto-generated method stub
		return 0;
	}

	/**
	 * @param prohibitedDomain
	 * @param borderNode
	 * @param id2
	 * @param bw
	 * @param wavelength
	 * @return
	 */
	public int[] getBestMultidomainPathF(Vector<Integer> bedDomains, int borderNode, int domainId, int resources, Integer wavelength) {
		// TODO Auto-generated method stub
		return new int[0];
	}
		
	

}
